/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MyStatementExecution.MySelect;

import MyDatabaseHandler.DatabaseHandler;
import MyCondition.AndOrHandler;
import MyStatementExecution.MyStatement;
import MyStatementExecution.MyStatementKind;
import MyDataContainer.*;
import StringJoinerCutter.StringJoinerCutter;
import java.util.ArrayList;

/**
 *
 * @author Welcome
 */
public class MySelectStatement extends MyStatement{

    //<editor-fold defaultstate="collapsed" desc="1/ Các thuộc tính cơ bản">
    private MyDataString selectFields;
    private ArrayList<MyQuery> fromQuerys;
    private AndOrHandler whereAndOrHandler;
    private MyDataString groupByFields;
    private String havingString;
    private MyDataString orderByFields;
    
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="2/ Các phương thức khởi tạo">
    public MySelectStatement() {
        myStatementKind = MyStatementKind.SELECT;
        initialize();
    }
    
    private void initialize()
    {
        selectFields=new MyDataString();
        fromQuerys=new ArrayList<MyQuery>();
        groupByFields=new MyDataString();
        havingString="";
        orderByFields=new MyDataString();
        whereAndOrHandler= new AndOrHandler();
    }
    public MySelectStatement(DatabaseHandler _databaseHandler,String _statementString) {
        this.databaseHandler=_databaseHandler;
        this.statementString=_statementString;
        initialize();
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="3/Cac phương thức Getter/Setter">
    @Override
    public MyStatementKind getKind() {
        return myStatementKind;
    }
    
    public void setDatabaseHandler(DatabaseHandler databaseHandler) {
        this.databaseHandler = databaseHandler;
    }
    
    public void setStatementString(String statementString) {
        this.statementString = statementString;
    }
    
    public void setInfo(DatabaseHandler _databaseHandler,String _statementString)
    {
        this.databaseHandler=_databaseHandler;
        this.statementString=_statementString;
    }
    //</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc="4/ Các phương thức xử lý nghiệp vụ">
    @Override
    public void executeStatement() {
        
    }
    
    public MyQuery executeSelectStatement() {
        MyQuery finalResult = processSelectStatement();
        //TODO HERE xu ly tiep finalresult theo yeu cau (gui ve client)
        finalResult.showData();
        return finalResult;
    }
   
    private MyQuery processSelectStatement() {
        MyQuery resultQuery = new MyQuery();
        splitComponent();
        
        
        if(fromQuerys.size()==1)
            {
                //Select tren 1 bảng, lọc dữ liệu theo điều kiện
                MyQuery tempQuery=fromQuerys.get(0);
                MyDataString tempColumn = tempQuery.getColumnTitles();
                for(int i=0; i<tempColumn.getSize();i++)
                {
                    tempColumn.setContentAt(i, tempQuery.getName()+"."+tempColumn.getAt(i));
                }
                resultQuery=processSelectOnOneTable(tempQuery);
            }
            else
            {
                //Select tren nhieu bang, co join
                resultQuery=processSelectOnMultiTables();
            }
        
        return resultQuery;
    }
    
    private void splitComponent() {
        try{
            String tempString="";
            
            //Select
            tempString = StringJoinerCutter.getStringInMidle(statementString, "select", "from");
            setSelectFields(tempString);
            

            //from
            tempString = StringJoinerCutter.getStringInMidle(statementString, "from", "where");
            setFromQuery(tempString);
            
            //where
            tempString = StringJoinerCutter.getStringInMidle(statementString, "where", "groupby");
            setWhereCondition(tempString);
            
            //To Do HERE : mở rộng cho having, groupby
            //.......

            
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    private void setSelectFields(String tempString) {
        String[] tempListStrings = tempString.split(",");
            selectFields.setData(tempListStrings);
    }
    
    private void setFromQuery(String tempString) {
        String[] tempListStrings = tempString.split(",");
            
            for(int i=0;i<tempListStrings.length;i++)
            {
                MyQuery tempQuery = new MyQuery(databaseHandler.getTable(tempListStrings[i].trim()));
                fromQuerys.add(tempQuery);
            }
    }
    
    private void setWhereCondition(String tempString) {
        whereAndOrHandler.setConditionString(tempString);
        whereAndOrHandler.splitConditions();
        
    }
    
    private MyQuery processSelectOnOneTable(MyQuery myQuery) {
        MyQuery resultQuery = new MyQuery(myQuery);
        ArrayList<String> andCondition = whereAndOrHandler.getAndConditions();
        ArrayList<String> orCondition = whereAndOrHandler.getOrConditions();
        
        //Xử lý cho các điều kiện and
        for(int i =0;i<andCondition.size();i++)
        {
            resultQuery=resultQuery.filterCondition(andCondition.get(i),databaseHandler);
        }
        
        MyQuery tempOrTable=new MyQuery(myQuery);
        
        //Xử lý cho các điều kiện or
        for(int i=0; i < orCondition.size(); i++)
        {
            
            MyQuery temp2 = tempOrTable.filterCondition(orCondition.get(i),databaseHandler);
            ArrayList<MyDataSet> tempDatas = new ArrayList<MyDataSet>(temp2.getRowContents());
            
            for(int j=0; j<tempDatas.size();j++)
                resultQuery.addContent(tempDatas.get(j));
        }
        
        //Loai bo cac dong trung lap
        for(int i=0; i<resultQuery.getSize()-1;i++)
        {
            for(int j=i+1;j<resultQuery.getSize();j++)
                if(resultQuery.getRowAt(i).isEqual(resultQuery.getRowAt(j)))
                {
                    resultQuery.removeAt(j);
                }
        }
        
        
        //Lọc các fields trong phần select
        if(!selectFields.getAt(0).equals("*"))
            resultQuery = resultQuery.filterSelect(selectFields);
        
        return resultQuery;
    }

    private MyQuery processSelectOnMultiTables() {
        MyQuery resultQuery = new MyQuery();
        
        resultQuery= MyQuery.fullOuterJoinQuery(fromQuerys);
        
        resultQuery=processSelectOnOneTable(resultQuery);
        return  resultQuery;
    }
    
    //</editor-fold>

    
    
}
